package com.cskaoyan.javase.oop1._11static._2compare;

import java.util.Scanner;

/**
 * static与非static比较
 * 当我们了解static成员的特点后，静态成员和非静态成员的区别就很明显
 * 我们从以下四个角度比较（拿成员变量为例）
 * 1.成员的所属
 *      成员变量: 属于对象,必须创建对象才能够使用它.
 *      静态成员变量: 属于类,无需创建对象,只要类加载后,就可以使用它
 *          类加载的触发方式很多,不仅仅有new对象
 *          即便内存中不存在任何对象,静态成员变量也可能存在
 *
 * 2.在内存中的位置
 *      成员变量: 存储在堆上的对象中
 *      静态成员变量: 存储在堆上被共享的区域
 *
 * 3.在内存中出现的时间
 *      成员变量: 必须在创建对象之后才存在
 *      静态成员变量: 类加载之后就存在
 *      静态成员变量一定出现的更早,在它出现的时候,还没有成员变量
 *
 * 4.调用方式
 *      成员变量: 对象名点
 *      静态成员变量: 类名点,从语法上来说,可以用"对象名点",但是不要这么做
 *
 * 静态成员方法和普通成员方法的区别和上述类似，我们主要思考以下两个问题就可以了：
 *      1.在静态方法中，能否访问非静态的成员吗?，为什么？
 *          不能,原因是静态成员存在时,非静态成员不存在,想访问也访问不了
 *          成员方法中隐含this传参
 *          static修饰的方法,没有this传参,实际上学完static以后,知道它"想有也有不了"
 *
 *      2.在普通成员方法中，能否访问静态成员，为什么？
 *          可以
 *          因为对象都有了
 *          类加载必然结束了
 *          静态成员早就存在了
 *          访问它们是可以的
 *
 *          实际上构造器,成员方法中,都是可以访问静态成员的
 *
 *
 * 静态成员变量的赋值:
 *      1.默认初始化,最先进行
 *      2.显式赋值,在默认初始化之后执行
 *      以上都是类加载过程中的赋值手段
 *
 *      以下是创建对象过程中的赋值手段
 *      1.构造器赋值
 *      2.成员方法赋值
 *
 *      创建对象必然在类加载之后,所以如果有创建对象过程中的赋值
 *      那么必然覆盖类加载过程中的赋值
 *      当然,实际开发中,很少见到在创建对象过程中,给静态成员变量赋值
 *
 *
 * @since 11:03
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        System.out.println(Student.schoolName);
        Student s = new Student();
        System.out.println(Student.schoolName);
    }
}

class Student {
    int age;
    static String schoolName = "北大";

    public Student() {
        schoolName = "清华";
    }

    public void test3() {
        System.out.println(schoolName);
        test2();
    }

    public static void test2() {
    }

    public static void test() {
        // Non-static field 'age' cannot be referenced from a static context
        // System.out.println(age);
        System.out.println(schoolName);
        test2();
    }
}